package com.cdsxt.genCode.service;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.ArrayUtils;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.w3c.dom.ls.LSInput;

import com.cdsxt.genCode.dao.TableDao;
import com.cdsxt.genCode.vo.GenCodeFieldVo;
import com.cdsxt.genCode.vo.GenCodeModuleVo;
import com.cdsxt.util.FileUtil;
import com.cdsxt.util.FreeMarkerUtil2;
import com.cdsxt.util.JdbcUtil;
import com.cdsxt.util.JsonObj;
import com.cdsxt.util.JsonUtil;
import com.cdsxt.util.StringUtils;

/**
 * 
 * @author 成都尚学堂 & mr zeng
 * 客服热线：028-65176856
 * 网址： www.cd-sxt.com
 * 
 * @param <PoCls>传入当前dao层对应的po类型
 */
@Service
public class GenCodeService {

	
	/**
	 * 解析配置数据
	 * 批量生成多个模块代码
	 */
	//@Test
	public void batchGenModuleCode(String jsonConfigPath) {
		
		String charSetName="utf-8";
		String genCodeConfigJsonStr = FileUtil.readCharFileInfo(jsonConfigPath, charSetName);
		JsonObj jsonObj = JsonUtil.jsonStrToJsonObj(genCodeConfigJsonStr);
		GenCodeModuleVo[] mdArr = JsonUtil.jsonStrToArr(JsonUtil.objToJsonStr(jsonObj.getAutoConvertTypeVal("listModule")), GenCodeModuleVo.class);
		for (GenCodeModuleVo md : mdArr) {
			genModuleCode1(md);
		}
	}
	
	
	/**
	 * 通过json字符串生成一个模块代码
	 */
	//@Test
	public void genModuleCodeJson(String moduleInfoJonStr) {
		GenCodeModuleVo md = JsonUtil.jsonStrToBean(moduleInfoJonStr, GenCodeModuleVo.class);
		genModuleCode1(md);
	}
	/**
	 * 通过json字符串生成一个模块代码
	 */
	//@Test
	public void genModuleCodeJsonArr(String moduleInfoJonStrArr) {
		GenCodeModuleVo[] arr = JsonUtil.jsonStrToArr(moduleInfoJonStrArr, GenCodeModuleVo.class);
		genModuleCode1Arr(arr);
	}
	
	public void genModuleCode1Arr(GenCodeModuleVo[] arr) {
		for (GenCodeModuleVo md : arr) {
			genModuleCode1(md);
		}
	}
	
	/**
	 * 【单表crud】
	 * 通过json对象生成一个模块代码
	 */
	public void genModuleCode1(GenCodeModuleVo moduleData) {
		
//		String className=moduleData.getClassName();
//		String tableName=moduleData.getTableName();
//		String moduleInfo=moduleData.getModuleInfo();
//		List<GenCodeFieldVo> listField=moduleData.getListField();
//		
//		String moduleName=className.substring(0, 1).toLowerCase()+className.substring(1);
//		
//		Map<String, Object> paramData=new HashMap<>();
//		paramData.put("moduleName", moduleName);
//		paramData.put("moduleInfo", moduleInfo);
//		paramData.put("className", className);
//		paramData.put("tableName", tableName);
//		paramData.put("listField", listField);
		/**
		 * TODO 如果是表反向产生的java代码==》那么不需要生成id，createdate和updatedate信息
		 * po，mapper都需要改！
		 */
		//生成各个模块
		//controller代码
		String controllerTemplate="genCodeTemplate/XXXController.java";
		String controllerCode = FreeMarkerUtil2.getOutString(moduleData, controllerTemplate);
		FileUtil.writeStringDataToFile("src/main/java/com/cdsxt/controller/"+moduleData.getClassName()+"Controller.java", "utf-8", controllerCode);
		//service代码
		String serviceTemplate="genCodeTemplate/XXXService.java";
		String serviceCode = FreeMarkerUtil2.getOutString(moduleData, serviceTemplate);
		FileUtil.writeStringDataToFile("src/main/java/com/cdsxt/service/"+moduleData.getClassName()+"Service.java", "utf-8", serviceCode);
		//dao代码
		String daoTemplate="genCodeTemplate/XXXDao.java";
		String daoCode = FreeMarkerUtil2.getOutString(moduleData, daoTemplate);
		FileUtil.writeStringDataToFile("src/main/java/com/cdsxt/dao/"+moduleData.getClassName()+"Dao.java", "utf-8", daoCode);
		//po代码
		String poTemplate="genCodeTemplate/XXXPo.java";
		String poCode = FreeMarkerUtil2.getOutString(moduleData, poTemplate);
		FileUtil.writeStringDataToFile("src/main/java/com/cdsxt/po/"+moduleData.getClassName()+"Po.java", "utf-8", poCode);
		//jsp查询页面
		String findJspTemplate="genCodeTemplate/XXXfind.jsp";
		String findJspCode = FreeMarkerUtil2.getOutString(moduleData, findJspTemplate);
		findJspCode=findJspCode.replaceAll("XXX", "\\$");
		FileUtil.mkdirs("src/main/webapp/views/page/"+moduleData.getModuleName());
		FileUtil.writeStringDataToFile("src/main/webapp/views/page/"+moduleData.getModuleName()+"/find.jsp", "utf-8", findJspCode);
		
		//jsp表单页面
		String formJspTemplate="genCodeTemplate/XXXform.jsp";
		String formJspCode = FreeMarkerUtil2.getOutString(moduleData, formJspTemplate);
		formJspCode=formJspCode.replaceAll("XXX", "\\$");
		FileUtil.mkdirs("src/main/webapp/views/page/"+moduleData.getModuleName());
		FileUtil.writeStringDataToFile("src/main/webapp/views/page/"+moduleData.getModuleName()+"/form.jsp", "utf-8", formJspCode);
		
		//mapper文件
		String mapperxmlTemplate="genCodeTemplate/XXX-mapper.xml";
		String mapperxmlCode = FreeMarkerUtil2.getOutString(moduleData, mapperxmlTemplate);
		mapperxmlCode=mapperxmlCode.replaceAll("XXX", "#");
		mapperxmlCode=mapperxmlCode.replaceAll("YYY", "\\$");
		FileUtil.mkdirs("src/main/java/com/cdsxt/dao/mapper");
		FileUtil.writeStringDataToFile("src/main/java/com/cdsxt/dao/mapper/"+moduleData.getModuleName()+"-mapper.xml", "utf-8", mapperxmlCode);
		
	}
	
	
	@Test
	public void deleteGenCode() {
		//删除controller除去common的文件
		deleteDirSubFile("src/main/java/com/cdsxt/controller", "common");
		//删除service
		deleteDirSubFile("src/main/java/com/cdsxt/service");
		//删除dao
		deleteDirSubFile("src/main/java/com/cdsxt/dao");
		//删除po
		deleteDirSubFile("src/main/java/com/cdsxt/po");
		//删除view page除去index.jsp
		deleteDirSubFile("src/main/webapp/views/page","index.jsp");
		System.out.println("删除完成！");
	}
	private void deleteDirSubFile(String dirPath,String ... noDelFiles) {
		File file=new File(dirPath);
		File[] listFiles = file.listFiles();
		if (listFiles==null) {
			return;
		}
		for (File subFile : listFiles) {
			if (noDelFiles!=null&&ArrayUtils.contains(noDelFiles, subFile.getName())) {
				continue;
			}
			if (subFile.isDirectory()) {
				//文件夹则递归删除
				deleteDirSubFile(subFile.getAbsolutePath());
			}
			//文件直接删除
			subFile.delete();
		}
	}
	
	
	@Autowired
	private TableDao tableDao;
	
	
	/**
	 * 得到连接的数据库所有表对应的所有的模块
	 * @return
	 */
	public GenCodeModuleVo[] getConnectedDataBaseListModule(String ... tableNames){
		
		List<String>  ignoreColumns=Arrays.asList("id","create_date","update_date");
		/**
		 * 读取连接的数据库所有表信息:产生所有的模块
		 */
		List<Map<String,?>> listTable=null;
		//所有的表
		if (ArrayUtils.isEmpty(tableNames)) {
			listTable= tableDao.selectListTable();
		}else {
			listTable= tableDao.selectListTableForNames(TableDao.Util.getListStr(Arrays.asList(tableNames)));
		}
		 
		//所有的模块
		List<GenCodeModuleVo> listModule=new ArrayList<>();
		
		//遍历多个表产生多个模块
		for (Map<String,?> table : listTable) {
			String tableName =(String) table.get("TABLE_NAME");
			String moduleInfo =(String) table.get("TABLE_COMMENT");
			String className=StringUtils.underlineToCamelStr(tableName, true);
			String moduleName=StringUtils.underlineToCamelStr(tableName, false);
			//TODO 不同的数据库版本处理不一样
//			String [] moduleInfoArr= moduleInfo.split(";");
//			moduleInfo=moduleInfoArr.length==1?"":moduleInfoArr[0];
			//创建模块
			GenCodeModuleVo md=new GenCodeModuleVo(moduleInfo, className,moduleName ,tableName,new ArrayList<>());
			List<Map<String, ?>> listFieldInfo = tableDao.selectListTableColumn(tableName);
			//遍历表的多个列产生模块的多个属性
			for (Map<String, ?> field : listFieldInfo) {
				String columnName =(String) field.get("COLUMN_NAME");
				String fieldName=StringUtils.underlineToCamelStr(columnName, false);
				/**
				 * TODO 需要忽略列：id，createDate，update
				 */
				if (ignoreColumns.contains(columnName)) {
					continue;
				}
				String fieldType=JdbcUtil.getJavaTypeforMysqlType((String) field.get("DATA_TYPE"));
				String fieldInfo=(String) field.get("COLUMN_COMMENT");
				GenCodeFieldVo  fd=new GenCodeFieldVo(fieldName, fieldType, fieldInfo,columnName);
				md.getListField().add(fd);
			}
			listModule.add(md);
		}
		GenCodeModuleVo[] moduleArr = listModule.toArray(new GenCodeModuleVo[listModule.size()]);
		
		return moduleArr;
	}
	

	
}
